package cluster

import (
	"gitee.com/cooge/impush/cluster/conn"
	"gitee.com/cooge/impush/core"
	log "github.com/sirupsen/logrus"
	"runtime"
	"time"
)

var timeLayout = "2006-01-02 15:04:05.999999999"

type ClusterConnUser struct {
	*conn.ClusterConn
	time *time.Time
}

func NewClusterConnUser(co *conn.ClusterConn, st string) *ClusterConnUser {
	tt, err := time.Parse(timeLayout, st)
	if err != nil {
		log.Debug("时间格式转换错误", err)
	}
	ccu := &ClusterConnUser{co, &tt}
	return ccu
}

func addHandlerFunc(userid string, value interface{}) {
	if isClusterUser(value) {
		log.Debug("集群用户，不向其它机器发送", userid)
	} else {
		sendAddUser(userid)
	}
}
func deleteHandlerFunc(userid string, value interface{}, ti *time.Time) {
	if isClusterUser(value) {
		log.Debug("集群用户，不向其它机器发送", userid)
	} else {
		sendDeleteUser(userid, ti)
	}
}
func addUserFilter() {
	userFilter := core.NewFilterHandlerFunc(addHandlerFunc, deleteHandlerFunc)
	core.AddFilter(userFilter)
}
func isClusterUser(value interface{}) bool {
	switch value.(type) {
	case *ClusterConnUser:
		{
			return true
		}
	}
	return false
}
func addClusterUser(userid string, cu *ClusterConnUser) {

	log.Debug("添加集群用户", userid, "用户时间", cu.time)

	cs := core.GetUser(userid)
	if cs != nil {
		var isExit = false
		for _, v := range cs {
			if isClusterUser(v) {
				u, ok := v.(*ClusterConnUser)
				if ok {
					if cu.ClusterConn == u.ClusterConn {
						isExit = true
						if u.time.Before(*cu.time) {
							core.AddUser(userid, cu)
							core.DeleteUser(userid, u)
						}
					}
				}
			}
		}
		if !isExit {
			core.AddUser(userid, cu)
		}
	} else {
		core.AddUser(userid, cu)
	}
}
func deleteClusterUser(userid string, cu *ClusterConnUser) {
	log.Debug("删除集群用户", userid, "用户时间", cu.time)
	cs := core.GetUser(userid)
	if cs != nil {
		for _, v := range cs {
			if isClusterUser(v) {
				u, ok := v.(*ClusterConnUser)
				if ok {
					if cu.ClusterConn == u.ClusterConn {
						if u.time.Equal(*cu.time) || u.time.Before(*cu.time) {
							core.DeleteUser(userid, u)
						}
					}
				}
			}
		}
	}

}

func deleteClusterConnUser(cu *conn.ClusterConn) {

	for num, userid := range core.GetALLUsers() {
		cs := core.GetUser(userid)
		if cs != nil {
			for _, v := range cs {
				if isClusterUser(v) {
					u, ok := v.(*ClusterConnUser)
					if ok {
						if cu == u.ClusterConn {
							core.DeleteUser(userid, u)
						}
					}
				}
			}
		}
		if num>>7<<7 == num {
			runtime.Gosched()
		}
	}
}

func deleteClusterConnUserId(userid string, cu *conn.ClusterConn) {
	cs := core.GetUser(userid)
	if cs != nil {
		for _, v := range cs {
			if isClusterUser(v) {
				u, ok := v.(*ClusterConnUser)
				if ok {
					if cu == u.ClusterConn {
						core.DeleteUser(userid, u)
					}
				}
			}
		}
	}
}
